package com.tanhua.server.serivce;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.cloud.commons.lang.StringUtils;
import com.alibaba.fastjson.JSON;
import com.tanhua.autoconfig.template.HuanXinTemplate;
import com.tanhua.dubbo.api.*;
import com.tanhua.model.db.Question;
import com.tanhua.model.db.UserInfo;
import com.tanhua.model.mongo.RecommendUser;
import com.tanhua.model.mongo.Visitors;
import com.tanhua.model.vo.NearUserVo;
import com.tanhua.model.vo.PageResult;
import com.tanhua.model.vo.TodayBest;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;

import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class TanhuaService {

    @DubboReference
    private RecommendUserApi recommendUserApi;

    @DubboReference
    private QuestionApi questionApi;

    @DubboReference
    private UserInfoApi userInfoApi;

    @DubboReference
    private UserLocationApi userLocationApi;

    @DubboReference
    private VisitorsApi visitorsApi;

    @DubboReference
    private UserlikeApi userlikeApi;
    @DubboReference
    private FriendApi friendApi;

    /**
     * 查询今日佳人
     *   需求：根据toUserId查询推荐的用户数据，展示缘分值最高的1条。
     */
    public TodayBest todayBest() {
        //1、获取当前用户id
        Long toUserId = UserHolder.getUserId();
        //2、调用api查询推荐用户数据 RecommentUser
        RecommendUser ru = recommendUserApi.queryWithMaxScore(toUserId);
        //对于新用户，没有推荐数据
        if(ru == null) {
            ru = new RecommendUser();
            ru.setUserId(1l); //模拟推荐的用户id
            ru.setScore(95D); //模拟推荐的评分
        }
        //3、将RecommentUser封装成TodayBest
        //3.1 查询UserInfo
        UserInfo userInfo = userInfoApi.findById(ru.getUserId());//toUserId是当前登录用户
        //3.2 根据UserInfo和RecommendUser构造vo
        TodayBest vo = TodayBest.init(userInfo, ru);
        //4、返回
        return vo;
    }

    /**
     * 根据toUserId查询推荐用户列表
     *   PageResult --  List<TodayBest>
     */
//    public PageResult recommendation(Integer page, Integer pagesize) {
//        //1、获取当前用户id
//        Long toUserId = UserHolder.getUserId();
//        //2、调用API分页查询推荐的用户列表  List<RecommendUser>
//        List<RecommendUser> list = recommendUserApi.queryRecommendUserList(page,pagesize,toUserId);
//        //3、对于新用户，没有推荐数据，构造默认假数据
//        if(CollUtil.isEmpty(list)) {
//            list = defaultList();
//        }
//        //4、一个RecommendUser封装一个TodayBest
//        List<TodayBest> vos = new ArrayList<>();
//        for (RecommendUser recommendUser : list) {
//            //查询当前推荐的用户的信息
//            UserInfo userInfo = userInfoApi.findById(recommendUser.getUserId());  //循环调用获取用户详情数据
//            TodayBest vo = TodayBest.init(userInfo, recommendUser);
//            vos.add(vo);
//        }
//        //5、构造返回
//        return new PageResult(page,pagesize,0l,vos);
//    }


    public PageResult recommendation(Integer page, Integer pagesize) {
        //1、获取当前用户id
        Long toUserId = UserHolder.getUserId();
        //2、调用API分页查询推荐的用户列表  List<RecommendUser>
        List<RecommendUser> list = recommendUserApi.queryRecommendUserList(page,pagesize,toUserId);
        //3、对于新用户，没有推荐数据，构造默认假数据
        if(CollUtil.isEmpty(list)) {
            list = defaultList();
        }
        //获取list中的所有推荐的用户id
        List<Long> userIds = CollUtil.getFieldValues(list,"userId",Long.class) ;//从list集合中，获取某个属性的所有值
        //调用UserInfoAPi,一次性查询所需要的所有用户信息 ：Map<用户id，UserInfo>
        Map<Long,UserInfo> map = userInfoApi.findByIds(userIds);
        //4、一个RecommendUser封装一个TodayBest
        List<TodayBest> vos = new ArrayList<>();
        for (RecommendUser recommendUser : list) {
            //调用API，从数据库中查询
            UserInfo userInfo = map.get(recommendUser.getUserId());
            TodayBest vo = TodayBest.init(userInfo, recommendUser);
            vos.add(vo);
        }
        //5、构造返回
        return new PageResult(page,pagesize,0l,vos);
    }

    private List<RecommendUser> defaultList() {
        List<RecommendUser> list = new ArrayList<>();
        //构造默认推荐数据，企业中按照项目经理要求
        for (int i = 1; i <= 10; i++) {
            RecommendUser ru = new RecommendUser();
            ru.setUserId((long) i); //模拟推荐的用户id
            ru.setScore(95D); //模拟推荐的评分
            list.add(ru);
        }
        return list;
    }

    //查看佳人信息        userId=查看的用户id          toUserId当前用户id
    public TodayBest personalInfo(Long userId) {
        //1、查询查看的用户的详情
        UserInfo userInfo = userInfoApi.findById(userId);
        //2、获取查看的用户和当前用户的缘分值（推荐信息）
        Long toUserId = UserHolder.getUserId();
        RecommendUser user = recommendUserApi.queryByUserId(userId,toUserId);
        //* 记录访客数据
        //userId -- 被查看人的用户id ，toUserId--当前操作用户（访客的用户id）
        Visitors visitors = new Visitors();
        visitors.setUserId(userId);
        visitors.setVisitorUserId(toUserId);
        visitors.setFrom("首页");
        visitors.setDate(System.currentTimeMillis());
        String visitDate = new SimpleDateFormat("yyyyMMdd").format(new Date());
        visitors.setVisitDate(visitDate);
        visitors.setScore(user.getScore());
        visitorsApi.save(visitors);

        return TodayBest.init(userInfo,user);
    }



    //查看指定用户的陌生人问题
    public String strangerQuestions(Long userId) {
        Question question = questionApi.findByUserId(userId);
        return question == null ? "你喜欢java吗":question.getTxt();
    }

    @Autowired
    private HuanXinTemplate huanXinTemplate;

    /**
     * 回复陌生人问题
     *  目标：
     *      通过java服务端，向对方发送一条系统消息
     *  参数：
     *    userId:对方的userId
     *    reoly：我回复的陌生人问题
     *      {"userId":106,"huanXinId":"hx106","nickname":"黑马小妹",
     *      "strangerQuestion":"你喜欢去看蔚蓝的大海还是去爬巍峨的高山？",
     *      "reply":"我喜欢秋天的落叶，夏天的泉水，冬天的雪地，只要有你一切皆可~"}
     *      "userId":106,"huanXinId"  谁发的就是谁的    谁回复的就是谁的
     */
    public void reply(Long userId, String reply) {
        //1、创建Map集合
        Map map = new HashMap<>();
        //2、按照数据格式要求，设置参数
        Long currUserId = UserHolder.getUserId();
        map.put("userId",currUserId);
        map.put("huanXinId","hx"+currUserId);
        UserInfo userInfo = userInfoApi.findById(currUserId);
        map.put("nickname",userInfo.getNickname());
        map.put("strangerQuestion",strangerQuestions(userId)); //陌生人问题
        map.put("reply",reply);
        //3、将对象转化为json
        //FastJson
        //JSON.toJSONString(对象) ;//将对象转化成json字符串
        //JSON.parseObject("json字符串",对象.class) ;//将json字符串转化为java对新
        String message = JSON.toJSONString(map);
        //4、调用组件发送消息
        huanXinTemplate.sendMsg("hx"+userId,message); //环信的用户名，消息内容
    }
    //查询附近的人
    public List<NearUserVo> search(String gender, String distance) {
        //1、获取用户id
        Long userId = UserHolder.getUserId();
        //2、调用api，根据当前用户的位置，查询附近的人 （用户id，距离distance）,返回附近人的id   List<Userlocation>
        List<Long> userIds = userLocationApi.searchNear(userId,distance);
        //3、根据附近人的所有id，查询用户详情
        Map<Long, UserInfo> map = userInfoApi.findByIds(userIds);
        //4、构造vo，返回 一个List<Long> userIds 构建一个 List<NearUserVo>
        List<NearUserVo> vos = new ArrayList<>();
        for (Long id : userIds) {
            //解决附近的人，查询出自己的bug
            if(id == userId) {
                continue;
            }
            UserInfo userInfo = map.get(id);
            if(userInfo!=null) { //为了防止空指针
                if(StringUtils.isEmpty(gender) || gender.equals(userInfo.getGender())) {//判断性别不为空或性别是否一致
                    NearUserVo vo = NearUserVo.init(userInfo);
                    vos.add(vo);
                }
            }
        }
        return vos;
    }

    //探花: 展示卡片功能
    public List<TodayBest> showCards(Integer page,Integer pagesize) {

        //1、获取当前用户id
        Long UserId = UserHolder.getUserId();
        //2、调用API分页查询推荐的用户列表  List<RecommendUser>
        List<RecommendUser> list = recommendUserApi.queryRecommendUserList(page,pagesize,UserId);
        //3、对于新用户，没有推荐数据，构造默认假数据
        if(CollUtil.isEmpty(list)) {
            list = defaultList();
        }
        //获取list中的所有推荐的用户id
        List<Long> userIds = CollUtil.getFieldValues(list,"userId",Long.class) ;//从list集合中，获取某个属性的所有值
        //调用UserInfoAPi,一次性查询所需要的所有用户信息 ：Map<用户id，UserInfo>
        Map<Long,UserInfo> map = userInfoApi.findByIds(userIds);
        //4、一个RecommendUser封装一个TodayBest
        List<TodayBest> vos = new ArrayList<>();
        for (RecommendUser recommendUser : list) {
            //调用API，从数据库中查询
            UserInfo userInfo = map.get(recommendUser.getUserId());
            TodayBest vo = TodayBest.init(userInfo, recommendUser);
            vos.add(vo);
        }
        //5、构造返回
        return vos;
    }


//    @DubboReference
//    private UserLikeApi userLikeApi;
//探花: 右滑保存喜欢数据

    public void love(Long likeUserId) {
        //1.右滑后,将数据保存至user_like表,对应类UserLike
        //1.1查询当前用户Id
        Long userId = UserHolder.getUserId();
        //1.2调用Api的save方法,根据当前用户Id与喜欢用户Id保存数据至user_like表
        userlikeApi.saveLike(userId,likeUserId);  //TODO


        //2.查询喜欢用户是否也喜欢当前用户,是,就加为好友记录到Friend表
        //2.1 调用Api的isLike方法,拿到bool值
        Boolean isLike = userlikeApi.isLike(likeUserId,userId);
        //2.2 判断是否互相喜欢
        if (isLike){
            //加好友
            friendApi.save(userId,likeUserId);
            //记录环信好友
            //环信删除好友
            huanXinTemplate.addContact("hx"+userId,"hx"+likeUserId);
            //huanXinTemplate.addContact(userId.toString(),likeUserId.toString());
        }

        //3.右滑后,从当前用户的推荐表中删除喜欢用户,不在重复推荐
        recommendUserApi.delete(userId,likeUserId);
    }


    //探花: 左滑不喜欢,删除推荐数据
    public void unlove(Long unLikeUserId) {
        //删除推荐数据
        recommendUserApi.delete(UserHolder.getUserId(),unLikeUserId);
        //删除环信好友
        //环信删除好友
        huanXinTemplate.deleteContact("hx"+UserHolder.getMobile(),"hx"+unLikeUserId);
        //huanXinTemplate.deleteContact(UserHolder.getMobile().toString(),unLikeUserId.
    }
}
